package com.dmc.controller;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dmc.conf.Constant;
import com.dmc.dict.UserLevelDict;
import com.dmc.dict.WxLoginTypeDict;
import com.dmc.dto.AuthTokenDTO;
import com.dmc.jwt.AuthTokenDetails;
import com.dmc.jwt.JsonWebTokenUtility;
import com.dmc.model.*;
import com.dmc.service.DistributionService;
import com.dmc.service.UserAccountService;
import com.dmc.service.UserService;
import com.dmc.util.SessionUtil;
import com.dmc.util.id.IdUtil;
import com.dmc.util.util.WXBizDataCrypt;
import com.dmc.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.security.provider.MD5;

import java.math.BigDecimal;
import java.util.*;

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Api(value = "用户相關接口",tags = {"UserController"})
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private DistributionService distributionService;

    private JsonWebTokenUtility tokenService = new JsonWebTokenUtility();

    /**
     * 用户登录
     *
     * @param u 用户对象
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ApiOperation(value = "后台登录接口")
    public AuthTokenDTO login(@RequestBody User u) {
        AuthTokenDTO authToken = null;

        User user = userService.login(u);

        if (user != null) {
            Integer stop = user.getStop();
            //Assert.isTrue(stop!=null && stop == 0,"您的账户因为"+user.getStopDes()+",平台作封号处理,如需申诉请联系平台客服");
            AuthTokenDetails authTokenDetails = new AuthTokenDetails();
            authTokenDetails.setId(user.getId());
            authTokenDetails.setUsername(user.getUsername());
            authTokenDetails.setExpirationDate(buildExpirationDate());
            authTokenDetails.setRoleNames(userService.getUserRoleNames(user.getId()));

            // Create auth token
            String jwt = tokenService.createJsonWebToken(authTokenDetails);
            if (jwt != null) {
                authToken = new AuthTokenDTO();
                authToken.setToken(jwt);
                authToken.setUserId(user.getId());
                authToken.setName(user.getName());
                authToken.setResourceList(userService.resourceList(user.getId()));
            }
        } else {
            throw new RuntimeException("用户名或密码错误");
        }

        return authToken;
    }

    /**
     * 微信小程序用户登录
     * @param u 用户对象
     * @return
     */
    @RequestMapping(value = "/wx_login", method = RequestMethod.POST)
    @ApiOperation(value = "微信小程序用户登录")
    public RestRespResult<AuthTokenDTO> wxLogin(@RequestBody User u) {
        log.info("UserController wxLogin shaId:{}",u.getShareUserId());
        AuthTokenDTO authToken = null;
        String iv = u.getIv();
        JSONObject openIdObject = WXBizDataCrypt.getOpenId(u.getCode(), iv);
        Assert.notNull(openIdObject,"登录失败,获取opendId失败");
        String openId = openIdObject.getString("openid");
        Assert.isTrue(StringUtils.isNotBlank(openId),"登录失败,无openId");
        //获取微信session_key密钥
        String sessionKey = openIdObject.getString("session_key");
        Assert.isTrue(StringUtils.isNotBlank(openId),"登录失败,无openId");
        User user = userService.getUserByOpenId(openId);
        if (user != null) {
            Integer stop = user.getStop();
            //Assert.isTrue(stop!=null && stop == 0,"您的账户因为"+user.getStopDes()+",平台作封号处理,如需申诉请联系平台客服");
        } else {
            String userinfo=WXBizDataCrypt.decrypt1(u.getEncryptedData(),sessionKey,iv);
            log.info("UserController wxLogin userinfo:{}",userinfo);
            if(StringUtils.isBlank(userinfo)){
                userinfo = u.getUserInfo();
            }
            JSONObject userinfoObject = JSON.parseObject(userinfo);
            log.info("UserController wxLogin userinfo:{}",userinfo);
            //新建用户
            user = u;
            user.setOpenId(openId);
            user.setUsername(userinfoObject.getString("nickName"));
            user.setName(userinfoObject.getString("nickName"));
            user.setCity(userinfoObject.getString("city"));
            user.setProvince(userinfoObject.getString("province"));
            user.setCountry(userinfoObject.getString("country"));
            user.setUserPhoto(userinfoObject.getString("avatarUrl"));
            user.setSex(userinfoObject.getInteger("gender"));
            user.setPassword(openId);
            user.setType(1);
            user.setStop(0);
            user.setLevel(0);
            user.setShareRewardsHave(0);
            user.setShareGoodsRewardsHave(0);
            user.setDistributionTotalPrice(BigDecimal.ZERO);
            Long shareUserId = u.getShareUserId();
            long id = IdUtil.generateId();
            user.setId(id);
            log.info("wxLogin shareUserId:{}",shareUserId);
            if(shareUserId!=null&&shareUserId!=0){
                //查询分享人是否是会员
                User userShare = userService.get(shareUserId);
                Integer level = userShare.getLevel();
                if(level!=null && level > UserLevelDict.USER_LEVEL_0.getCn()){
                    user.setShareUserId(shareUserId);
                }else{
                    user.setShareUserId(id);
                }
            }else{
                user.setShareUserId(id);
            }
            userService.addUser(user);
            DistributionShareRelation relation = new DistributionShareRelation();
            relation.setCreateTime(new Date());
            relation.setUserId(user.getId());
            relation.setShareUserId(user.getShareUserId());
            relation.setOrderId(null);
            distributionService.insertRelation(relation);
            //授权为客户角色
            List<Long> roleIds = new ArrayList<>();
            roleIds.add(Constant.CLIENT_ROLE_ID);
            user.setRoleIds(roleIds);
            grant(user);
            //初始化账户表
            TUserAccount acc = new TUserAccount();
            acc.setUserId(user.getId());
            acc.setBenefit(BigDecimal.ZERO);
            acc.setIntegral(BigDecimal.ZERO);
            acc.setCreateTime(new Date());
            userAccountService.save(acc);
        }
        AuthTokenDetails authTokenDetails = new AuthTokenDetails();
        authTokenDetails.setId(user.getId());
        authTokenDetails.setUsername(user.getUsername());
        authTokenDetails.setExpirationDate(buildExpirationDate());
        authTokenDetails.setRoleNames(userService.getUserRoleNames(user.getId()));
        String jwt = tokenService.createJsonWebToken(authTokenDetails);
        if (jwt != null) {
            authToken = new AuthTokenDTO();
            authToken.setToken(jwt);
            authToken.setUserId(user.getId());
            authToken.setName(user.getName());
            authToken.setResourceList(userService.resourceList(user.getId()));
            authToken.setOpenId(openId);
            authToken.setSessionKey(sessionKey);
            authToken.setPhone(user.getUserPhone());
        }
        RestRespResult result = RestRespResult.ok("登录成功");
        result.setData(authToken);
        return result;
    }



    private Date buildExpirationDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 1);
        return calendar.getTime();
    }

    @RequestMapping(value="/getUserList",method = RequestMethod.POST)
    @ApiOperation(value = "获取会员列表")
    public RestRespResult<DataTable<UserInfoVO>>  getUserList(@RequestBody UserInfoVO vo) {
        DataTable<UserInfoVO> table = userService.getUserList(vo);
        RestRespResult result = RestRespResult.ok("获取会员列表成功");
        result.setData(table);
        return result;
    }

    @RequestMapping(value="/uddateSharePhone",method = RequestMethod.POST)
    @ApiOperation(value = "修改推荐人")
    public RestRespResult<String>  uddateSharePhone(Long id,String shareUserPhone) {
        userService.uddateSharePhone(id,shareUserPhone);
        RestRespResult result = RestRespResult.ok("修改推荐人");
        return result;
    }

    @RequestMapping(value="/getUserByPhone",method = RequestMethod.GET)
    @ApiOperation(value = "根据手机号获取用户",tags = {"三期"})
    public RestRespResult<User>  getUserByPhone(@ApiParam(value="用户手机号",name="phone") String phone) {
        User user = userService.getUserByPhone(phone);
        RestRespResult result = RestRespResult.ok("根据手机号获取用户成功");
        result.setData(user);
        return result;
    }

    @RequestMapping(value = "/getVipConfigList", method = RequestMethod.GET)
    @ApiOperation(value = "获取会员荣誉身份列表",tags = {"三期"})
    @ResponseBody
    public RestRespResult<List<VipConfigVo>> getVipConfigList(@ApiParam(value="1:停用 0:正常使用 不传查所有",name="status")@RequestParam(required=false)Integer status) {
        RestRespResult result = RestRespResult.ok("添加会员荣誉身份成功");
        List<VipConfigVo> vipConfigList = userService.getVipConfigList(status);
        result.setData(vipConfigList);
        return result;
    }


    @RequestMapping(value = "/addVipConfig", method = RequestMethod.POST)
    @ApiOperation(value = "添加会员荣誉身份",tags = {"三期"})
    @ResponseBody
    public RestRespResult<String> addVipConfig(@RequestBody VipConfigVo vo) {
            RestRespResult result = RestRespResult.ok("添加会员荣誉身份成功");
        userService.addVipConfig(vo);
        return result;
    }

    @RequestMapping(value = "/updateVipConfig", method = RequestMethod.POST)
    @ApiOperation(value = "更新会员荣誉身份",tags = {"三期"})
    @ResponseBody
    public RestRespResult<String> updateVipConfig(@RequestBody VipConfigVo vo) {
        RestRespResult result = RestRespResult.ok("更新会员荣誉身份成功");
        userService.updateVipConfig(vo);
        return result;
    }

    @RequestMapping(value="/updateUserStatus",method = RequestMethod.POST)
    @ApiOperation(value = "禁用/启用会员",tags = {"二期"})
    public RestRespResult<DataTable<UserInfoVO>>  closeUser(@RequestBody UserVO vo) {
        userService.closeUser(vo);
        Integer stop = vo.getStop();
        stop = stop == null?0:stop;
        RestRespResult result = RestRespResult.ok(stop == 0?"启用成功":"禁用成功");
        return result;
    }

    @RequestMapping(value = "/transferProfit", method = RequestMethod.POST)
    @ApiOperation(value = "转让收益",tags = {"三期"})
    @ResponseBody
    public RestRespResult<String> transferProfit(@RequestBody TransferProfitVo vo) {
        RestRespResult result = RestRespResult.ok("更新会员荣誉身份成功");
        userService.transferProfit(vo);
        return result;
    }



    @RequestMapping(value="/sendMsgCode",method = RequestMethod.POST)
    @ApiOperation(value = "发送验证码")
    public RestRespResult<String>  sendMsgCode(@RequestBody QueryBaseVo queryBaseVo) {
        userService.sendMsgCode(queryBaseVo.getPhone(), queryBaseVo.getType());
        RestRespResult result = RestRespResult.ok("发送验证码成功");
        return result;
    }

    @RequestMapping(value="/sendMsg",method = RequestMethod.POST)
    @ApiOperation(value = "发送短信")
    public RestRespResult<String>  sendMsg(@RequestBody QueryBaseVo queryBaseVo) {
        userService.sendMsg(queryBaseVo);
        RestRespResult result = RestRespResult.ok("发送短信成功");
        return result;
    }

    @RequestMapping(value="/getUserAccount",method = RequestMethod.GET)
    @ApiOperation(value = "获取用户账户信息")
    public RestRespResult<TUserAccount>  getUserAccount() {
        TUserAccount acc = userAccountService.initUserAccountByUserId(SessionUtil.getCurrUid());
        RestRespResult result = RestRespResult.ok("获取用户账户信息成功");
        result.setData(acc);
        return result;
    }

    @RequestMapping(value="/getUserDiscount",method = RequestMethod.GET)
    @ApiOperation(value = "获取用户折扣信息")
    public RestRespResult<UserDisCountVo>  getUserDiscount() {
        UserDisCountVo acc = userService.getDisCount(SessionUtil.getCurrUid());
        RestRespResult result = RestRespResult.ok("获取用户账户信息成功");
        result.setData(acc);
        return result;
    }

    @RequestMapping(value="/bindPhone",method = RequestMethod.POST)
    @ApiOperation(value = "绑定手机号")
    public RestRespResult<String>  bindPhone(String phone) {
        Assert.notBlank(phone,"缺少参数,请传输手机号");
        userService.bindPhone(phone);
        RestRespResult result = RestRespResult.ok("绑定手机号成功");
        return result;
    }

    @RequestMapping(value="/getWxPhoneNum",method = RequestMethod.POST)
    @ApiOperation(value = "解析微信数据获取微信手机号")
    public RestRespResult<String>  getWxPhoneNum(@RequestBody WxParamVo u) {
        String iv = u.getIv();
        String sessionKey = u.getSession_key();
        String userinfo=WXBizDataCrypt.decrypt1(u.getEncryptedData(),sessionKey,iv);
        Assert.isTrue(StringUtils.isNotBlank(userinfo),"获取手机号失败,未获取到用户信息");
        JSONObject userinfoObject = JSON.parseObject(userinfo);
        RestRespResult result = RestRespResult.ok("绑定手机号成功");
        result.setData(userinfoObject.getString("phoneNumber"));
        return result;
    }

    @RequestMapping(value="/checkMsgCode",method = RequestMethod.POST)
    @ApiOperation(value = "校验验证码")
    public RestRespResult<String> checkMsgCode(@RequestBody QueryBaseVo queryBaseVo) {
        userService.checkMsgCode(queryBaseVo.getPhone(),queryBaseVo.getCode(),queryBaseVo.getType());
        RestRespResult result = RestRespResult.ok("验证验证码成功");
        return result;
    }


    @RequestMapping(value="/updateUserWx",method = RequestMethod.POST)
    @ApiOperation(value = "小程序更新用户信息")
    public RestRespResult<String> updateUserWx(@RequestBody User u) {
        userService.updateUserWx(u);
        RestRespResult result = RestRespResult.ok("更新用户信息成功");
        return result;
    }

    @RequestMapping(value="/getUserCenterInfo",method = RequestMethod.POST)
    @ApiOperation(value = "小程序个人中心信息",tags = {"三期"})
    public RestRespResult<UserCenterInfoVO> getUserCenterInfo() {
        Long currUid = SessionUtil.getCurrUid();
        UserCenterInfoVO vo = userService.getUserCenterInfo(currUid);
        RestRespResult result = RestRespResult.ok("获取个人信息成功");
        result.setData(vo);
        return result;
    }


    /**
     * 添加用户
     *
     * @return
     */
    @RequestMapping(method = RequestMethod.POST)
    @ApiOperation(value = "添加用户")
    public User add(@RequestBody User user) {
        userService.add(user);
        return user;
    }


    /**
     * 修改用户
     */
    @RequestMapping(method = RequestMethod.PUT)
    @ApiOperation(value = "修改用户")
    public User edit(@RequestBody User user) {
        Long id = user.getId();
        if(id == null){
            user.setId(SessionUtil.getCurrUid());
        }
        userService.edit(user);
        return user;
    }


    @RequestMapping(value = "/tables", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户列表")
    public DataTable<User> tables(@RequestBody UserVO userVO) {
        return userService.tables(userVO);
    }


    /**
     * 用户详情
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
    @ApiOperation(value = "获取单个用户详情")
    public User getUserById(@PathVariable("userId") Long userId) {
        User user = userService.get(userId);
        user.setPassword(null);
        return user;
    }

    /**
     * 删除用户
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除用户")
    public RestResp delete(@PathVariable("userId") Long userId) {
        Long currUid = SessionUtil.getCurrUid();
        if (Objects.equals(userId, currUid)) {// 不能删除自己
            return RestResp.error(RestResp.ERROR, "不能删除自己");
        }

        userService.delete(userId);

        return RestResp.ok("删除成功");
    }

    /**
     * 批量删除用户
     *
     * @param ids ('0','1','2')
     * @return
     */
    @RequestMapping(value = "/batchDelete", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量删除用户")
    public void batchDelete(String ids) {
        if (ids != null && ids.length() > 0) {
            for (String id : ids.split(",")) {
                this.delete(Long.valueOf(id));
            }
        }
    }

    /**
     * 用户授权
     */
    @RequestMapping(value = "/grant", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "修改用户关联角色")
    public RestResp grant(@RequestBody User user) {
        userService.grant(user);
        return RestResp.ok("授权成功！");
    }


    /**
     * 编辑用户密码
     *
     * @param user
     * @return
     */
    @RequestMapping("/editPwd")
    @ApiOperation(value = "修改用户密码")
    public RestResp editPwd(@RequestBody User user) {
        userService.editPwd(user);
        return RestResp.ok("编辑成功");
    }





    /**
     * 修改自己的密码
     *
     * @param user
     * @return
     */
    @ApiOperation(value = "修改自己密码")
    @RequestMapping(value = "/editCurrentUserPwd", method = RequestMethod.POST)
    @ResponseBody
    public RestResp editCurrentUserPwd(@RequestBody User user) {
        Long currUid = SessionUtil.getCurrUid();

        if (currUid != null) {
            if (!userService.editCurrentUserPwd(currUid, user.getOldPassword(), user.getPassword())) {
                throw new RuntimeException("原密码错误！");
            }
        } else {
            throw new RuntimeException("登录超时，请重新登录！");
        }

        return RestResp.ok("修改成功");
    }
}
